"""
AI报告配置管理模块

提供统一的配置管理，包括PDF生成、OSS上传、AI服务等各种配置。
支持从环境变量、配置文件等多种方式加载配置。
"""

from dataclasses import dataclass
from typing import Dict, Any, Optional
import os
import tempfile
import pdfkit


@dataclass
class PDFConfig:
    """PDF生成配置"""
    wkhtmltopdf_path: str
    temp_dir: str
    options: Dict[str, Any]
    
    @classmethod
    def from_env(cls) -> 'PDFConfig':
        """从环境变量创建PDF配置"""
        return cls(
            wkhtmltopdf_path=os.getenv('WKHTMLTOPDF_PATH', r'E:\\wkhtmltopdf\\bin\\wkhtmltopdf.exe'),
            temp_dir=tempfile.gettempdir(),
            options={
                'encoding': 'UTF-8',
                'custom-header': [('Accept-Charset', 'UTF-8')],
                'enable-local-file-access': None,
                'page-size': 'A4',
                'margin-top': '0.75in',
                'margin-right': '0.75in',
                'margin-bottom': '0.75in',
                'margin-left': '0.75in',
                'no-outline': None
            }
        )


@dataclass
class OSSConfig:
    """OSS上传配置"""
    endpoint: str
    bucket: str
    access_key_id: str
    access_key_secret: str
    base_url: str
    
    @classmethod
    def from_env(cls) -> 'OSSConfig':
        """从环境变量创建OSS配置"""
        return cls(
            endpoint=os.getenv('OSS_ENDPOINT', 'https://oss-cn-shenzhen.aliyuncs.com'),
            bucket=os.getenv('OSS_BUCKET', 'landiwulian'),
            access_key_id=os.getenv('OSS_ACCESS_KEY_ID', ''),
            access_key_secret=os.getenv('OSS_ACCESS_KEY_SECRET', ''),
            base_url=os.getenv('OSS_BASE_URL', 'https://landiwulian.oss-cn-shenzhen.aliyuncs.com')
        )


@dataclass
class AIConfig:
    """AI服务配置"""
    default_provider: str
    timeout: int
    max_retries: int
    providers: Dict[str, Dict[str, Any]]
    
    @classmethod
    def from_env(cls) -> 'AIConfig':
        """从环境变量创建AI配置"""
        return cls(
            default_provider=os.getenv('AI_DEFAULT_PROVIDER', 'deepseek'),
            timeout=int(os.getenv('AI_TIMEOUT', '300')),
            max_retries=int(os.getenv('AI_MAX_RETRIES', '3')),
            providers={
                'deepseek': {
                    'api_key': os.getenv('DEEPSEEK_API_KEY', ''),
                    'base_url': os.getenv('DEEPSEEK_BASE_URL', 'https://api.deepseek.com'),
                    'model': os.getenv('DEEPSEEK_MODEL', 'deepseek-chat')
                },
                'openai': {
                    'api_key': os.getenv('OPENAI_API_KEY', ''),
                    'base_url': os.getenv('OPENAI_BASE_URL', 'https://api.openai.com'),
                    'model': os.getenv('OPENAI_MODEL', 'gpt-4o-mini')
                }
            }
        )


@dataclass
class DatabaseConfig:
    """数据库配置"""
    elasticsearch_hosts: list
    mongodb_url: str
    redis_url: str
    
    @classmethod
    def from_env(cls) -> 'DatabaseConfig':
        """从环境变量创建数据库配置"""
        return cls(
            elasticsearch_hosts=[
                host.strip() for host in 
                os.getenv('ELASTICSEARCH_HOSTS', 'http://119.23.229.39:39200').split(',')
            ],
            mongodb_url=os.getenv('MONGODB_URL', 'mongodb://localhost:27017/iot_wristband'),
            redis_url=os.getenv('REDIS_URL', 'redis://localhost:6379/0')
        )


@dataclass
class ReportConfig:
    """报告生成总配置"""
    pdf_config: PDFConfig
    oss_config: OSSConfig
    ai_config: AIConfig
    database_config: DatabaseConfig
    
    # 报告相关配置
    batch_size: int = 100
    base_timestamp: int = 1735660800  # 2025-01-01 00:00:00 UTC
    default_timezone: str = 'Asia/Shanghai'
    
    # 文件命名配置
    file_name_patterns: Dict[str, str] = None
    
    def __post_init__(self):
        """初始化后处理"""
        if self.file_name_patterns is None:
            self.file_name_patterns = {
                'worker': 'bangni/report/{member_name}_{depart_name}工作分析报告_{timestamp}.pdf',
                'equipment': 'bangni/report/{member_name}设备工作分析报告_{timestamp}.pdf',
                'project': 'bangni/report/{member_name}-{project_name}设备工作分析报告_{timestamp}.pdf'
            }
    
    @classmethod
    def from_env(cls) -> 'ReportConfig':
        """从环境变量创建完整配置"""
        return cls(
            pdf_config=PDFConfig.from_env(),
            oss_config=OSSConfig.from_env(),
            ai_config=AIConfig.from_env(),
            database_config=DatabaseConfig.from_env(),
            batch_size=int(os.getenv('REPORT_BATCH_SIZE', '100')),
            base_timestamp=int(os.getenv('REPORT_BASE_TIMESTAMP', '1735660800')),
            default_timezone=os.getenv('REPORT_DEFAULT_TIMEZONE', 'Asia/Shanghai')
        )
    
    def get_file_name_pattern(self, report_type: str) -> str:
        """获取指定报告类型的文件名模式"""
        return self.file_name_patterns.get(report_type, 
                                         'bangni/report/{member_name}报告_{timestamp}.pdf')
    
    def get_pdf_kit_config(self) -> pdfkit.configuration:
        """获取pdfkit配置对象"""
        return pdfkit.configuration(wkhtmltopdf=self.pdf_config.wkhtmltopdf_path)
    
    def get_oss_base_url(self) -> str:
        """获取OSS基础URL"""
        return self.oss_config.base_url
    
    def get_ai_provider_config(self, provider_name: str = None) -> Dict[str, Any]:
        """获取AI服务提供商配置"""
        if provider_name is None:
            provider_name = self.ai_config.default_provider
        
        return self.ai_config.providers.get(provider_name, {})
    
    def validate_config(self) -> bool:
        """验证配置是否完整"""
        try:
            # 检查PDF配置
            if not os.path.exists(self.pdf_config.wkhtmltopdf_path):
                raise ValueError(f"wkhtmltopdf路径不存在: {self.pdf_config.wkhtmltopdf_path}")
            
            # 检查OSS配置
            if not all([self.oss_config.access_key_id, self.oss_config.access_key_secret]):
                raise ValueError("OSS配置不完整，缺少access_key_id或access_key_secret")
            
            # 检查AI配置
            default_provider = self.ai_config.default_provider
            if default_provider not in self.ai_config.providers:
                raise ValueError(f"默认AI提供商'{default_provider}'未在providers中配置")
            
            provider_config = self.ai_config.providers[default_provider]
            if not provider_config.get('api_key'):
                raise ValueError(f"AI提供商'{default_provider}'缺少api_key配置")
            
            # 检查数据库配置
            if not self.database_config.elasticsearch_hosts:
                raise ValueError("Elasticsearch主机配置为空")
            
            return True
            
        except Exception as e:
            raise ValueError(f"配置验证失败: {str(e)}")


# 全局配置实例
_global_config: Optional[ReportConfig] = None


def get_report_config() -> ReportConfig:
    """获取全局报告配置实例"""
    global _global_config
    if _global_config is None:
        _global_config = ReportConfig.from_env()
        _global_config.validate_config()
    return _global_config


def set_report_config(config: ReportConfig):
    """设置全局报告配置实例"""
    global _global_config
    config.validate_config()
    _global_config = config